package com.xtayfjpk.security.certificate;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;

import javax.security.auth.x500.X500Principal;

import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.junit.Test;

public class UserCertGenerator {
	
	private static final String ALIAS = "gitblit certificate authority";
	private static final String KEY_STORE_PWD = "gitblit";


	@Test
	public void main() throws Exception {
		String alias = ALIAS;
		KeyStore caKeyStore = getGitblitKeyStore();
		X509Certificate caCertificate = (X509Certificate) caKeyStore.getCertificate(alias);
		
		
		X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
		certGen.setIssuerDN(caCertificate.getSubjectX500Principal());
		certGen.setNotAfter(new Date(System.currentTimeMillis()+ 100 * 24 * 60 * 60 * 1000));
		certGen.setNotBefore(new Date());
		certGen.setPublicKey(getZhangsanPublicKey());
		certGen.setSerialNumber(BigInteger.TEN);
		certGen.setSignatureAlgorithm("SHA1withRSA");
		certGen.setSubjectDN(new X500Principal("CN=zhangsan,OU=development,O=Huawei,L=ShenZhen,ST=GuangDong,C=CN"));
		PrivateKey privateKey = (PrivateKey) caKeyStore.getKey(ALIAS, KEY_STORE_PWD.toCharArray());
		X509Certificate certificate = certGen.generate(privateKey);
		
		FileOutputStream fos = new FileOutputStream("H:/certtest/zhangsan.cer");
		fos.write(certificate.getEncoded());
		fos.close();
		
		KeyStore zsKeyStore = KeyStore.getInstance("pkcs12");
		zsKeyStore.load(new FileInputStream("C:\\Users\\zj\\Desktop\\caKeyStore.p12"), KEY_STORE_PWD.toCharArray());
		zsKeyStore.setKeyEntry("zhangsan", getZhangsanPrivateKey(), KEY_STORE_PWD.toCharArray(), new Certificate[]{certificate});
		zsKeyStore.store(new FileOutputStream("C:\\Users\\zj\\Desktop\\zhangsan.p12"), KEY_STORE_PWD.toCharArray());
	}
	
	public static KeyStore getGitblitKeyStore() throws Exception {
		String path = UserCertGenerator.class.getResource("/caKeyStore.p12").getFile();
		KeyStore keyStore = KeyStore.getInstance("pkcs12");
		InputStream stream = new FileInputStream(path);
		String password = KEY_STORE_PWD;
		keyStore.load(stream, password.toCharArray());
		stream.close();
		return keyStore;
	}
	public static PrivateKey getGitblitPrivateKey() throws Exception {
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\zj\\Desktop\\ca.privatekey"));
		Object result =  ois.readObject();
		ois.close();
		return (PrivateKey) result;
	}
	
	@Test
	public void testZhangsanKeyPair() throws Exception {
		KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
		keyPairGenerator.initialize(1024);
		KeyPair keyPair = keyPairGenerator.generateKeyPair();
		ObjectOutputStream publicOut = new ObjectOutputStream(new FileOutputStream("H:/certtest/zhangsan.public"));
		publicOut.writeObject(keyPair.getPublic());
		publicOut.close();
		ObjectOutputStream privateOut = new ObjectOutputStream(new FileOutputStream("H:/certtest/zhangsan.private"));
		privateOut.writeObject(keyPair.getPrivate());
		privateOut.close();
	}
	
	
	public PublicKey getZhangsanPublicKey() throws Exception {
		ObjectInputStream publicIn = new ObjectInputStream(new FileInputStream("H:/certtest/zhangsan.public"));
		PublicKey publicKey = PublicKey.class.cast(publicIn.readObject());
		publicIn.close();
		return publicKey;
	}
	
	public PrivateKey getZhangsanPrivateKey() throws Exception {
		ObjectInputStream privateIn = new ObjectInputStream(new FileInputStream("H:/certtest/zhangsan.private"));
		PrivateKey privateKey = PrivateKey.class.cast(privateIn.readObject());
		privateIn.close();
		return privateKey;
	}
}
